<?php

namespace App\Http\Controllers\Activity;

use App\App\Services\Web\UserService;
use App\Contracts\Repositories\ActivityRepository as ActivityRepositoryContact;
use App\Contracts\Services\Storage\StorageService;
use App\Entities\ActivityInfo;
use App\Exceptions\AppException;
use App\Http\Controllers\Controller;
use App\Entities\Activity;
use App\Entities\ActivityModel;
use Illuminate\Container\Container;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;

abstract class BaseController extends Controller
{
    protected $user;
    protected $activities;

    public function __construct(UserService $user, ActivityRepositoryContact $activities)
    {
        $this->user = $user;
        $this->activities = $activities;
    }

    abstract public function show($id);

    abstract protected function parseRules(Request $request);

    abstract protected function parseLimits(Request $request);

    abstract protected function getRulesForCreate();

    abstract protected function getRulesForUpdate();

    abstract protected function createdEvents( Activity $activity);

    abstract protected function updatedEvents(Activity $activity);

    public function store(Request $request)
    {
        $this->checkHttpHeaders($request);
        $input = $request->json()->all();
        $validator = Validator::make($input, $this->getRulesForCreate());
        if ($validator->fails()) {
            return response()->failed(Arr::first($validator->errors()->all()));
        }

        $input = $this->translateInputFromRequest($request);
//                var_dump($input);die;

        $activity = new Activity();
        $activity->fill($input);
        $database = Container::getInstance()->make('db');
        $success = $database->transaction(function () use ($activity) {
            $activity->save();
            return ActivityInfo::sync($activity);
        });
        if ($success) {
            // trigger events
            $this->createdEvents($activity);
            return response()->success(['id' => $activity->getAttribute('id')]);
        }
        return response()->failed('活动创建失败');
    }

    public function update(Request $request, $id)
    {
        $activity = Activity::query()->where('id', $id)->first();
        if (null === $activity) {
            return response()->failed('没有找到这个活动');
        }
        $input = $request->json()->all();
        $validator = Validator::make($input, $this->getRulesForUpdate());
        if ($validator->fails()) {
            return response()->failed(Arr::first($validator->errors()->all()));
        }

        $input = $this->translateInputFromRequest($request);
        // 去掉不可修改的值
        Arr::forget($input, ['user_id', 'group_code', 'model_id', 'template_id']);
        $activity->fill($input);

        $database = Container::getInstance()->make('db');

        $success = $database->transaction(function () use ($activity) {
            $activity->save();
            $info = ActivityInfo::query()->find($activity->getAttribute('id'));

            if (!$info) {
                return true;
            }

            $info->setAttribute('name', $activity->getAttribute('name'));
            return $info->save();
        });

        if ($success) {
            $this->updatedEvents($activity);
            return response()->success();
        }

        return response()->failed('活动修改失败');
    }

    protected function translateInputFromRequest(Request $request)
    {
        $raw = $request->json()->all();

        $input = array_filter($raw, function ($value) {
            return null !== $value;
        });
        return array_merge($input, [
            'isPause' => Arr::get($input, 'is_pause', Activity::PAUSED),
            'clicks' => 0,
            'joins' => 0,
            'winnings' => 0,
            'startTime' => Arr::get($input, 'start_time'),
            'endTime' => Arr::get($input, 'end_time'),
            'limit' => $this->parseLimits($request),
            'rule' => $this->parseRules($request),
            //'backgroundColor' => Arr::get($input, 'background_color', ''),
            'shares' => $this->parseShares($request),
            //'backgroundImg' => Arr::get($input, 'background_img', ''),
            'listBackgroundImg' => Arr::get($input, 'list_background_img', ''),
            'ruleDescription' => Arr::get($input, 'rule_description', ''),
            'user_id' => $request->session()->get('userid'),
            'group_code' => $request->session()->get('groupcode'),
            'description' => Arr::get($input, 'description', ''),
            'app_url' => Arr::get($input, 'app_url', ''),
            'publishing_ways' => Arr::get($input, 'publishing_ways', ''),
            'customId' => Arr::get($input,'customId',''),
            'organizer' => Arr::get($input,'organizer',''),
            'others' => Arr::get($input,'others',''),
            'remark' => Arr::get($input,'remark',''),
        ]);
    }

    public function checkHttpHeaders(Request $request)
    {
//        if (!$request->header('user-id')) {
//            throw new AppException('未携带UserId');
//        }
//
//        if (!$request->header('group-code')) {
//            throw new AppException('未携带GroupCode');
//        }
        if (!$request->session()->get('userid')) {
        throw new AppException('未携带UserId');
    }

        if (!$request->session()->get('groupcode')) {
            throw new AppException('未携带GroupCode');
        }
    }

    protected function parseShares(Request $request)
    {
        $shares = [
            'isopen' => $request->json('shares.isopen', 'off'),
            'title' => $request->json('shares.title', ''),
            'content' => $request->json('shares.content', ''),
            'icon' => $request->json('shares.thumb', $request->json('shares.icon', '')),
        ];

        return json_encode($shares);
    }

    protected function formatShares($raw)
    {
        if (empty($raw)) {
            return [
                'isopen' => 'off',
                'title' => '',
                'content' => '',
                'thumb' => '',
                'icon' => '',
            ];
        }

        $shares = json_decode($raw, true);
        $thumb = Arr::get($shares, 'icon', Arr::get($shares, 'thumb', ''));
        $thumb = app(StorageService::class)->toHttpUrl($thumb);

        return [
            'isopen' => Arr::get($shares, 'isopen', 'off'),
            'title' => Arr::get($shares, 'title', ''),
            'content' => Arr::get($shares, 'content', ''),
            'icon' => $thumb,
            'thumb' => $thumb,
        ];
    }
}
